#pragma once

#include <string>
#include <sstream>

namespace rpc {

// Logger interface for user to write log
class Logger {
public:
    virtual ~Logger() {}
    // Write log line
    // @param str log line
    virtual void write(const std::string& str) = 0;
};

struct _Logend {};

// Logger interface
class LogWriter {
    Logger* logger_ {nullptr}; ///< External Logger interface pointer
    std::stringstream ss_; ///< std::stringstream

public:
    LogWriter(Logger* logger);
    template <typename T>
    LogWriter& operator<<(const T& t) {
        ss_ << t;
        return *this;
    }

    LogWriter& operator<<(const _Logend&) {
        if (logger_) {
            logger_->write(ss_.str());
        }
        return *this;
    }
};

extern Logger* logger_;

#define Logbegin (rpc::LogWriter(rpc::logger_))
#define Logend (rpc::_Logend())


}
